package com.jic.veteran.common.pay;

import lombok.extern.slf4j.Slf4j;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@Slf4j
public class HttpConnectionV2Util {
	private static ConcurrentMap<String,String> typeMap = new ConcurrentHashMap<String,String>();
	private static HttpURLConnection conn = null;

//	static {
//		try {
//			init(connectUrl+transType);
//		} catch (Exception e) {
//			log.info("初始化连接失败:{}",e.getMessage());
//		}
//	}

	public HttpConnectionV2Util(String connectUrl){
		try {
			init(connectUrl);
		} catch (Exception e) {
			log.info("初始化连接失败:{}",e.getMessage());
		}
	}

	/*private static class HttpConnectionPayHolder {
		private final static HttpConnectionV2Util instance = new HttpConnectionV2Util("url");
	}

	private static class HttpConnectionQueryHolder {
		private final static HttpConnectionV2Util instance = new HttpConnectionV2Util("url");
	}
	private static class HttpConnectionGetHolder {
		private final static HttpConnectionV2Util instance = new HttpConnectionV2Util("url");
	}*/

	public static HttpConnectionV2Util getInstance(String type,String url) {
		if("pay".equals(type)) {
			return new HttpConnectionV2Util(url +type);
//			return HttpConnectionUtil.HttpConnectionPayHolder.instance;
		}
		if("query".equals(type)) {
			return new HttpConnectionV2Util(url +type);
//			return HttpConnectionUtil.HttpConnectionQueryHolder.instance;
		}
		if("get".equals(type)) {
			return new HttpConnectionV2Util(url +type);
//			return HttpConnectionUtil.HttpConnectionGetHolder.instance;
		}
		return null;
	}
	
	public static void init(String connectUrl) throws Exception{
		URL url = new URL(connectUrl);
		System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
	    HostnameVerifier hv = new HostnameVerifier() {
	         public boolean verify(String urlHostName, SSLSession session) {
	         return urlHostName.equals(session.getPeerHost());
	         }
	    };
	    HttpsURLConnection.setDefaultHostnameVerifier(hv);
		URLConnection urlConnection = url.openConnection();
		urlConnection.setDoInput(true);
		urlConnection.setDoOutput(true);
		urlConnection.setReadTimeout(60000);
		urlConnection.setConnectTimeout(30000);
    	if (urlConnection instanceof HttpsURLConnection){
    		HttpsURLConnection httpsConn = (HttpsURLConnection)urlConnection;
    		httpsConn.setSSLSocketFactory(SSLUtil.getInstance().getSSLSocketFactory());
    	} else if (urlConnection instanceof HttpURLConnection){
    		HttpURLConnection httpConn = (HttpURLConnection)urlConnection;
    	} else {
    		throw new Exception("不是http/https协议的url");
    	}
    	conn = (HttpURLConnection)urlConnection;
    	initDefaultPost(conn);
	}
	
	public void destory(){
		try{
			if(this.conn!=null){
				this.conn.disconnect();
			}
		}catch(Exception e){
			
		}
	}
	
    private static void initDefaultPost(HttpURLConnection conn) throws Exception{
    	conn.setDoOutput(true);
    	conn.setDoInput(true);
    	conn.setRequestMethod("POST");
    	conn.setUseCaches(false);
    	conn.setInstanceFollowRedirects(true);
    	conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    }
    
    public byte[] postParams(Map<String, String> params,boolean readreturn) throws IOException {
    	StringBuilder outBuf = new StringBuilder();
    	boolean isNotFirst = false;
    	for (Map.Entry<String, String> entry: params.entrySet()){
    		if (isNotFirst)
    			outBuf.append('&');
    		isNotFirst = true;
    		outBuf
    			.append(entry.getKey())
    			.append('=')
    			.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
    	}
		log.info("参数:{}",outBuf.toString());
		try {
			return postParams(outBuf.toString(),readreturn);
		} catch (IOException e) {
			throw new IOException(String.format("与通联交互失败:%s\n",e.getMessage()));
		}
	}
    
    public byte[] postParams(String message,boolean readreturn) throws IOException {
    	log.info("连接接类型 conn instanceof HttpsURLConnection ：{}",String.valueOf(conn instanceof HttpsURLConnection));
    	log.info("连接SSLSocketFactory;{}",((HttpsURLConnection)conn).getSSLSocketFactory().getSupportedCipherSuites());
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
    	out.write(message.getBytes("UTF-8"));
    	out.close();
    	if(readreturn){
    		return readBytesFromStream(conn.getInputStream());
    	}else{
    		return null;
    	}
    }
    
    public byte[] postParams(byte[] message,boolean readreturn) throws IOException {
    	DataOutputStream out = new DataOutputStream(conn.getOutputStream());
    	out.write(message);
    	out.close();
    	if(readreturn){
    		return readBytesFromStream(conn.getInputStream());
    	}else{
    		return null;
    	}
    }
    
    private byte[] readBytesFromStream(InputStream is) throws IOException{
    	ByteArrayOutputStream baos = new ByteArrayOutputStream();
    	int readLen;
    	byte[] tmpBuf = new byte[4096];
    	while ((readLen = is.read(tmpBuf)) > 0)
    		baos.write(tmpBuf, 0, readLen);
    	is.close();
    	return baos.toByteArray();
    }

	public HttpURLConnection getConn() {
		return conn;
	}
    
}
